// #include <iostream>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

// 易变关键字
volatile int flag = 0;//加上关键字表示此变量异变,不能预先加载到寄存器中

void change(int signo) // 信号捕捉的执行流
{
    (void)signo;

    flag = 1;
    printf("change flag 0->1, getpid: %d\n", getpid());
}

int main()
{
    printf("I am main process, pid is : %d\n", getpid());
    signal(2, change);

    while(!flag); // 主执行流--- flag我们没有做任何修改！
    printf("我是正常退出的!\n");
}

//g++ -o test -O3 sigtest.c // 编译器会优化直接因为检测到flag没有在主程序中修改,优化会把flag预先加载到cpu的寄存器中,内存中的flag修改了,但是寄存器中的未修改

//打印block表
// // printBLocklist
// void PirintBLock()
// {
//     sigset_t set, oset;
//     sigemptyset(&set);
//     sigemptyset(&oset);

//     sigprocmask(SIG_BLOCK, &set, &oset);
//     std::cout << "block: ";
//     for (int signo = 31; signo > 0; signo--)
//     {
//         if (sigismember(&oset, signo))
//         {
//             std::cout << 1;
//         }
//         else
//         {
//             std::cout << 0;
//         }
//     }
//     std::cout << std::endl;
// }


//打印pending表
// void PrintPending()
// {
//     sigset_t pending;
//     ::sigpending(&pending);

//     std::cout << "Pending: ";
//     for (int signo = 31; signo > 0; signo--)
//     {
//         if (sigismember(&pending, signo))
//         {
//             std::cout << 1;
//         }
//         else
//         {
//             std::cout << 0;
//         }
//     }
//     std::cout << std::endl;
// }


// void handler(int signo)
// {
//     static int cnt = 0;
//     cnt++;
//     while (true)
//     {
//         std::cout << "get a sig: " << signo << ", cnt: " << cnt << std::endl;
//         // PirintBLock();
//         PrintPending();
//         sleep(1);
//         // break;
//     }
//     // exit(1);
// }
//验证修改信号是在信号被递达时就已经处理把pending表修改为0了,而不是处理完毕的时候

// int main()
// {
//     struct sigaction act, oact;
//     act.sa_handler = handler;
//     sigemptyset(&act.sa_mask);
//     sigaddset(&act.sa_mask, 3);
//     sigaddset(&act.sa_mask, 4);
//     sigaddset(&act.sa_mask, 5);
//     sigaddset(&act.sa_mask, 6);
//     sigaddset(&act.sa_mask, 7);

//     ::sigaction(2, &act, &oact);

//     while (true)
//     {
//         // PirintBLock();
//         PrintPending();
//         pause();
//     }
// }